package jp.wug;

import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.servlet.RequestScoped;
import jp.wug.core.Page;
import jp.wug.core.PageFactory;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.Writer;

@RequestScoped
public class PageFlow {
    Injector injector;
    PageFactory pageFactory;
    WugRequest request;
    HttpServletResponse response;
    boolean handled;

    @Inject
    public PageFlow(Injector injector, PageFactory pageFactory, WugRequest request, HttpServletResponse response) {
        this.injector = injector;
        this.pageFactory = pageFactory;
        this.request = request;
        this.response = response;
    }

    public void redirectTo() {
        redirectTo(request.getModelClass());
    }

    public <T> void redirectTo(Class<T> modelClass) {
        redirectTo(modelClass, injector.getInstance(modelClass));
    }

    public <T, U extends T> void redirectTo(Class<T> modelClass, U object) {
        Page page = pageFactory.create(modelClass, object);
        String url = page.toPathInfoPlusQueryParameter();
        try {
            response.sendRedirect(url);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        handled = true;
    }

    public <T> void forwardTo(Class<T> modelClass) {
        forwardTo(modelClass, injector.getInstance(modelClass));
    }

    public <T, U extends T> void forwardTo(Class<T> modelClass, U model) {
        Page page = pageFactory.create(modelClass, model);

        response.setContentType("application/xhtml+xml");
        response.setCharacterEncoding("UTF-8");
        try {
            Writer writer = response.getWriter();
            writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
            page.write(writer);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        handled = true;
    }

//	public void push() {
//	}

//	public void pop() {
//	}

    boolean isHandled() {
        return handled;
    }

//    @SessionScoped
//    public static class Stack {
//    }
}